package le.grand;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.swing.table.AbstractTableModel;

public class FlightInfoTableModel extends AbstractTableModel {

	FlightInfo fi;
	int nameColumnSize;
	private List<InfoRow> rows = new ArrayList<>();

	public FlightInfoTableModel(FlightInfo fi, int nameColumnSize) {
		this.nameColumnSize = nameColumnSize;
		this.fi = fi;
		Set<String> hotelNames = fi.getHotels().keySet();
		System.out.println("***** HNames:" + hotelNames);
		Collection<HotelInfo> hotels = fi.getHotels().values();
		for (HotelInfo hotelInfo : hotels) {
			List<ReservationInfo> reservations = hotelInfo.getReservations();
			for (ReservationInfo ri : reservations) {
				List<ReservationEntry> entries = ri.getEntries();
				for (ReservationEntry re : entries) {
					String hname = hotelInfo.getHotelName();
					if (hname.length() > 20) {
						hname = hname.substring(0, 20);
					}
					hname += " (" + hotelInfo.getTotalNumOfPassengers() + ")";
					String names = formatNames(re.getNames());
					List<InfoRow> r2 = new ArrayList<>();
					if (names.length() > nameColumnSize) {
						String[] sr = split(names, nameColumnSize);
						names = sr[0];
						for (int i = 1; i < sr.length; i++) {
							r2.add(new InfoRow(hname, sr[i]));
						}
					}
					InfoRow r = new InfoRow(hname, names,
							Integer.toString(re.getNumOfPassengers()), Integer.toString(ri
									.getReservationNumber()));
					rows.add(r);
					rows.addAll(r2);
				}
			}
		}
	}

	private String formatNames(List<String> names) {
		StringBuilder sb = new StringBuilder();
		for (String s : names) {
			sb.append(s);
			sb.append(" ");
		}
		return sb.toString();
	}

	@Override
	public int getRowCount() {
		return rows.size();
	}

	@Override
	public int getColumnCount() {
		return 4;
	}

	@Override
	public String getColumnName(int column) {
		switch (column) {
		case 0:
			return "Hotel";
		case 1:
			return "Res";
		case 2:
			return "Names";
		case 3:
			return "Num";
		}
		return null;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		InfoRow r = rows.get(rowIndex);
		switch (columnIndex) {
		case 0:
			return r.hotel;
		case 1:
			return r.res;
		case 2:
			return r.names;
		case 3:
			return r.count;
		}
		return null;
	}

	private static class InfoRow {
		String hotel;
		String names;
		String count;
		String res;

		public InfoRow(String hotel, String names, String count, String res) {
			this.hotel = hotel;
			this.names = names;
			this.count = count;
			this.res = res;
		}

		public InfoRow(String hotel, String names) {
			this.hotel = hotel;
			this.names = names;
			this.count = "";
			this.res = "";
		}

	}

	private static String[] split(String s, int maxStrLen) {
		List<String> splits = new ArrayList<>();
		if (s.length() <= maxStrLen) {
			return new String[] { s };
		}
		String st = s;
		while (st.length() > maxStrLen) {
			splits.add(st.substring(0, maxStrLen));
			st = st.substring(maxStrLen + 1);
		}
		splits.add(st);
		return splits.toArray(new String[splits.size()]);
	}
}
